home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 2.iso / lprint / lprint.c < prev    next >
C/C++ Source or Header  |  1991-10-19  |  10KB  |  501 lines

  1. /*   lprint  :     landscape PRINT out utility for FM-TOWNS
  2.  *
  3.  *                Ver. 1.10     90/10/14
  4.  *
  5.  *         (C) Copyright    Makoto Sakai
  6.  *                      Nifty:    ムンパッパ (MHB02550)     
  7.  *                     junet:    sakai@sra.co.jp
  8.  *
  9.  * Permission to use, copy, modify, and distribute this software and its
  10.  * documentation for any purpose and without fee is hereby granted,
  11.  * provided that the above copyright notice appear in all copies and that
  12.  * both that copyright notice and this permission notice appear in
  13.  * supporting documentation.
  14.  */
  15. #include <stdio.h>
  16.  
  17. #define iskanji(c) (((c>0x80)&&(c<0xa0))||((c>0xdf)&&(c<0xfd)))
  18. #define WIDTH  112
  19. #define HEIGHT  76
  20. #define ANK      0
  21. #define KANJI    1
  22. #define KANJI2   2
  23. #define VLINE    0xff01
  24. #define HLINE    0xff02
  25. #define ULLINE   0xff03
  26. #define URLINE   0xff04
  27. #define DLLINE   0xff05
  28. #define DRLINE   0xff06
  29. #define LINE     0xff00
  30.  
  31. static unsigned short    data[WIDTH][HEIGHT];
  32. static int    lineno = 1;
  33. static int    pageno = 1;
  34. #ifdef NO
  35.     static int    noflag  = 1;
  36. #else
  37.     static int    noflag  = 0;
  38. #endif
  39. #ifdef FMPR
  40.     static int    fmflag = 1;
  41. #else
  42.     static int    fmflag = 0;
  43. #endif
  44. #ifdef B5
  45.     static int    b5flag = 1;
  46. #else
  47.     static int    b5flag = 0;
  48. #endif
  49. #ifdef QUICK
  50.     static int    quickflg = 1;
  51. #else
  52.     static int    quickflg = 0;
  53. #endif
  54. static int    width[] = {WIDTH,94};
  55. static int    height[] = {HEIGHT,64};
  56. static char    *name;
  57. static char    *init[] =    {"\033U\000\0333\030",    "\033Q24;180 G"};
  58. static int    initlen[] =    {6,            10};
  59. static char    *end[] =    {"\033@",        "\033c"};
  60. static int    endlen[] =    {2,            2};
  61. static char    *image[] =    {"\033*\047\022\000",    "\033Q18 W"};
  62. static int    imagelen[] =    {5,            6};
  63. static char    *skip[] =    {"\033\\\022\000",    "\033[18a"};
  64. static int    skiplen[] =    {4,            5};
  65.  
  66. static int    start_no = 0;
  67. static int    end_no = 0x7fffffff;
  68.  
  69. main(argc, argv)
  70. int    argc;
  71. char    *argv[];
  72. {
  73.     
  74.     register int    x;
  75.     register int    y;
  76.     static int    noteof = 1;
  77.     FILE    *ifp;
  78.     char    *envp;
  79.  
  80.     envp = (char *)getenv("LPRINT");
  81.     if (envp) {
  82.         flagset(envp);
  83.     }
  84.     argv++;
  85.     while (**argv == '-') {
  86.         (*argv)++;
  87.         flagset(*argv);
  88.         argc--;
  89.         argv++;
  90.     }
  91.     if (argc > 2) {
  92.         usage();
  93.         exit(1);
  94.     }
  95.     if (argc != 2) {
  96.         ifp = stdin;
  97.         name = "";
  98.     }
  99.     else {
  100.         if ((ifp = fopen(*argv,"r"))== NULL) {
  101.             fprintf(stderr,"Can't open %s\n",*argv);
  102.             exit(1);
  103.         }
  104.         name = *argv;
  105.     }
  106.     while(noteof && (pageno < start_no)) {
  107.         noteof = getpage(ifp);
  108.         pageno++;
  109.     }
  110.     if (!noteof) {
  111.         exit(0);
  112.     }
  113.     prnnput(initlen[fmflag], init[fmflag]);
  114.     while(noteof && (pageno <= end_no)) {
  115.         noteof = getpage(ifp);
  116.         for (x = 0; x < width[b5flag]; x++) {
  117.             for (y = height[b5flag]-1; y >= 0; y--) {
  118.                 imgput(data[x][y]);
  119.             }
  120.             imgnl();
  121.         }
  122.         for (y = height[b5flag]-1; y >= 0; y--) {
  123.             imgput(' ');
  124.         }
  125.         imgnl();
  126.         pageno++;
  127.         if (noteof && (pageno <= end_no)) {
  128.             noteof = getpage(ifp);
  129.             for (x = 0; x < width[b5flag]; x++) {
  130.                 for (y = height[b5flag]-1; y >= 0; y--) {
  131.                     imgput(data[x][y]);
  132.                 }
  133.                 imgnl();
  134.             }
  135.             pageno++;
  136.         }
  137.         imgflush();
  138.         prnputc('\f');
  139.     }
  140.     prnnput(endlen[fmflag], end[fmflag]);
  141.     exit(0);
  142. }
  143. clear(buf,size,len)
  144. unsigned char    *buf;
  145. int        size;
  146. int        len;
  147. {
  148.     register int    cnt1;
  149.     register int    max;
  150.  
  151.     max = size * len;
  152.     for (cnt1 = 0; cnt1 < max; ++cnt1) {
  153.         buf[cnt1] = 0;
  154.     }
  155. }
  156. usage()
  157. {
  158.     fprintf(stderr,"USAGE : lprint [option] file\n");
  159.     fprintf(stderr,"  -n  : number\n");
  160.     fprintf(stderr,"  -p  : plain(no number)\n");
  161.     fprintf(stderr,"  -b  : B5\n");
  162.     fprintf(stderr,"  -a  : A4\n");
  163.     fprintf(stderr,"  -f  : FMPR\n");
  164.     fprintf(stderr,"  -e  : ESC/P\n");
  165.     fprintf(stderr,"  -q  : quick\n");
  166.     fprintf(stderr,"  -c  : case\n");
  167.     fprintf(stderr,"  -s# : start at # page(# is decimal number)\n");
  168.     fprintf(stderr,"  -t# : to # page(# is decimal number)\n");
  169. }
  170. getpage(ifp)
  171. FILE    *ifp;
  172. {
  173.     register int    x,y;
  174.     register int    colmax,lowmax;
  175.     int    tabstop;
  176.     int    noteof = 1;
  177.     int    nlflag;
  178.     register unsigned char    c;
  179.     register unsigned short    s;
  180.     static unsigned long    startno;
  181.     static unsigned char lastc='\0';
  182.     static char buffer[BUFSIZ];
  183.     static char *bufp;
  184.  
  185.     colmax = width[b5flag] - 1;
  186.     lowmax = height[b5flag] - 1;
  187.     for (x = 0; (name[x] != '\0')&&(x < (colmax-1)); x++) {
  188.         data[x+1][0] = name[x];
  189.     }
  190.     if (!quickflg) {
  191.         for (x = 1; x < colmax; ++x) {
  192.             data[x][1] = VLINE;
  193.         }
  194.         for (x = 1; x < colmax; ++x) {
  195.             data[x][height[b5flag]-1] = VLINE;
  196.         }
  197.         for (y = 2; y < lowmax; ++y) {
  198.             data[0][y] = HLINE;
  199.         }
  200.         for (y = 2; y < lowmax; ++y) {
  201.             data[width[b5flag]-1][y] = HLINE;
  202.         }
  203.         data[0][1] = URLINE;
  204.         data[0][height[b5flag]-1] = ULLINE;
  205.         data[width[b5flag]-1][1] = DRLINE;
  206.         data[width[b5flag]-1][height[b5flag]-1] = DLLINE;
  207.     }
  208.     startno = lineno;
  209.     for (y = 2; y < lowmax; ++y) {
  210.         if (noflag) {
  211.             if (nlflag) {
  212.                 sprintf(buffer,"%5d: ", lineno);
  213.                 bufp = buffer;
  214.                 for (x = 1; x < 8; ++x) {
  215.                     data[x][y] = *bufp++;
  216.                 }
  217.             }
  218.             else {
  219.                 for (x = 1; x < 8; ++x) {
  220.                     data[x][y] = ' ';
  221.                 }
  222.             }
  223.         }
  224.         else {
  225.             x = 1;
  226.         }
  227.         for (; x < colmax; ++x) {
  228.             if (noteof == 1) {
  229.                 nlflag = 0;
  230.                 if (lastc) {
  231.                     c = lastc;
  232.                     lastc = '\0';
  233.                 }
  234.                 else {
  235.                     c = getc(ifp);
  236.                     noteof = (feof(ifp))?0:1;
  237.                 }
  238.                 if (!noteof) {
  239.                     if ((noflag)&&(x == 8)) {
  240.                         for (x = 1; x < 8; ++x) {
  241.                             data[x][y] = ' ';
  242.                         }
  243.                         lineno--;
  244.                     }
  245.                     else if (x == 1) {
  246.                         lineno--;
  247.                     }
  248.                     data[x][y] = ' ';
  249.                 }
  250.                 else {
  251.                     if (iskanji(c)) {
  252.                         if (x == (colmax - 1)) {
  253.                             lastc = c;
  254.                             data[x][y] = ' ';
  255.                             continue;
  256.                         }
  257.                         noteof = (feof(ifp))?0:1;
  258.                         s = (c<<8)+ getc(ifp);
  259.                         s = s2jis(s & 0xffff);
  260.                         if (s == (unsigned short)0xffff) {
  261.                             s = 0x2222;
  262.                         }
  263.                         data[x][y] = (s | 0x8000);
  264.                         x++;
  265.                         data[x][y] = s;
  266.                     }
  267.                     else if (c == '\n') {
  268.                         for (; x < colmax; ++x) {
  269.                             data[x][y] = ' ';
  270.                         }
  271.                         x--;
  272.                         lineno++;
  273.                         nlflag = 1;
  274.                     }
  275.                     else if (c == '\r') {
  276.                         ;
  277.                     }
  278.                     else if (c == '\t') {
  279.                         tabstop = (x + 8)& 0xfffffff8
  280.                                 + (noflag?0:1);
  281.                         if (tabstop > colmax) {
  282.                             tabstop = colmax;
  283.                         }
  284.                         for (; x < tabstop; ++x) {
  285.                             data[x][y] = ' ';
  286.                         }
  287.                         x--;
  288.                     }
  289.                     else if (c == '\b') {
  290.                         x -= 2;
  291.                         if (x < (noflag?7:0)) {
  292.                             x++;
  293.                         }
  294.                     }
  295.                     else if (c == '\f') {
  296.                         for (; x < colmax; ++x) {
  297.                             data[x][y] = ' ';
  298.                         }
  299.                         x--;
  300.                         lineno++;
  301.                         noteof = -1;
  302.                     }
  303.                     else if (c < 0x20) {
  304.                         data[x][y] = '.';
  305.                     }
  306.                     else {
  307.                         data[x][y] = c;
  308.                     }
  309.                 }
  310.             }
  311.             else {
  312.                 data[x][y] = ' ';
  313.             }
  314.         }
  315.     }
  316.     if (noflag) {
  317.         sprintf(buffer, "Page %d", pageno);
  318.         bufp = buffer;
  319.         for (x = width[b5flag] - strlen(buffer) - 2; *bufp != '\0'; x++) {
  320.             data[x][0] = *bufp++;
  321.         }
  322.     }
  323.     else {
  324.         sprintf(buffer,"%d - %d",startno,lineno-nlflag-((noteof==-1)?1:0));
  325.         bufp = buffer;
  326.         for (x = width[b5flag] - strlen(buffer) - 2; *bufp != '\0'; x++) {
  327.             data[x][0] = *bufp++;
  328.         }
  329.     }
  330.     return(noteof);
  331. }
  332.  
  333. static unsigned char    pbuf[WIDTH * 18][3];
  334. static int    dotcnt = 0;
  335. static int    linecnt = 0;
  336.  
  337. imgput(sdata)
  338. unsigned short    sdata;
  339. {
  340.  
  341.     static vdata[18] = {0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0};
  342.     static hdata[18] = {8,8,8,8,8,8,8,8,0x08,8,8,8,8,8,8,8,8,8};
  343.     static uldata[18] ={0,0,0,0,0,0,0,0,0x0f,8,8,8,8,8,8,8,8,8};
  344.     static urdata[18] ={8,8,8,8,8,8,8,8,0x0f,0,0,0,0,0,0,0,0,0};
  345.     static dldata[18] ={0,0,0,0,0,0,0,0,0xf8,8,8,8,8,8,8,8,8,8};
  346.     static drdata[18] ={8,8,8,8,8,8,8,8,0xf8,0,0,0,0,0,0,0,0,0};
  347.     static int *datap[] ={vdata, hdata, uldata, urdata, dldata, drdata};
  348.     register int    cnt;
  349.  
  350.     if ((sdata & LINE)== LINE) {
  351.         sdata -= LINE + 1;
  352.         for (cnt = 0; cnt < 18; ++cnt) {
  353.             pbuf[dotcnt++][linecnt] = datap[sdata][cnt];
  354.         }
  355.     }
  356.     else if (sdata == ' ') {
  357.         for (cnt = 0; cnt < 18; ++cnt) {
  358.             pbuf[dotcnt++][linecnt] = 0;
  359.         }
  360.     }
  361.     else if (sdata <= 0xff) {
  362.         for (cnt = 0; cnt < 16; ++cnt) {
  363.             pbuf[dotcnt++][linecnt] = getfnt(ANK,(int)sdata,15-cnt);
  364.         }
  365.         for (; cnt < 18; ++cnt) {
  366.             pbuf[dotcnt++][linecnt] = 0;
  367.         }
  368.     }
  369.     else if (sdata & 0x8000) {
  370.         sdata -= 0x8000;
  371.         for (cnt = 0; cnt < 16; ++cnt) {
  372.             pbuf[dotcnt++][linecnt] = 
  373.                     getfnt(KANJI,(int)sdata, (15-cnt)*2);
  374.         }
  375.         for (; cnt < 18; ++cnt) {
  376.             pbuf[dotcnt++][linecnt] = 0;
  377.         }
  378.     }
  379.     else {
  380.         for (cnt = 0; cnt < 16; ++cnt) {
  381.             pbuf[dotcnt++][linecnt] = 
  382.                     getfnt(KANJI,(int)sdata, (15-cnt)*2+1);
  383.         }
  384.         for (; cnt < 18; ++cnt) {
  385.             pbuf[dotcnt++][linecnt] = 0;
  386.         }
  387.     }
  388. }
  389. imgnl()
  390. {
  391.     linecnt++;
  392.     dotcnt = 0;
  393.     if (linecnt >= 3) {
  394.         imgflush();
  395.     }
  396. }
  397. imgflush()
  398. {
  399.     register int    dcnt;
  400.     register int    dotmax;
  401.  
  402.     if (dgetc() == 3) {
  403.         prnnput(3, "\r\n\f");
  404.         prnnput(endlen[fmflag], end[fmflag]);
  405.         fprintf(stderr,"abort\n");
  406.         exit(1);
  407.     }
  408.     if (linecnt != 0) {
  409.         dotmax = height[b5flag] * 18;
  410.         for (; linecnt < 3; ++linecnt) {
  411.             for (dcnt = 0; dcnt < dotmax; ++dcnt) {
  412.                 pbuf[dcnt][linecnt] = 0;
  413.             }
  414.         }
  415.         for (dcnt = 0; dcnt < dotmax; dcnt+=18) {
  416.             if (isskip(18 * 3, &pbuf[dcnt][0])) {
  417.                 prnnput(skiplen[fmflag], skip[fmflag]);
  418.             }
  419.             else {
  420.                 prnnput(imagelen[fmflag], image[fmflag]);
  421.                 prnnput(18 * 3, &pbuf[dcnt][0]);
  422.             }
  423.         }
  424.         prnnput(2, "\r\n");
  425.         linecnt = 0;
  426.         dotcnt = 0;
  427.     }
  428. }
  429. isskip(n, str)
  430. int    n;
  431. unsigned char    *str;
  432. {
  433.     while (n--) {
  434.         if (*str++) {
  435.             return(0);
  436.         }
  437.     }
  438.     return(1);
  439. }
  440. prnnput(n, str)
  441. int    n;
  442. unsigned char    *str;
  443. {
  444.     while (n--) {
  445.         prnputc(*str++);
  446.     }
  447. }
  448. flagset(option)
  449. char    *option;
  450. {
  451.     while (*option != '\0') {
  452.         switch (*option++) {
  453.             case    'p':
  454.             case    'P':
  455.                 noflag = 0;
  456.                 break;
  457.             case    'n':
  458.             case    'N':
  459.                 noflag = 1;
  460.                 break;
  461.             case    'f':
  462.             case    'F':
  463.                 fmflag = 1;
  464.                 break;
  465.             case    'e':
  466.             case    'E':
  467.                 fmflag = 0;
  468.                 break;
  469.             case    'b':
  470.             case    'B':
  471.                 b5flag = 1;
  472.                 break;
  473.             case    'a':
  474.             case    'A':
  475.                 b5flag = 0;
  476.                 break;
  477.             case    'q':
  478.             case    'Q':
  479.                 quickflg = 1;
  480.                 break;
  481.             case    'c':
  482.             case    'C':
  483.                 quickflg = 0;
  484.                 break;
  485.             case    's':
  486.             case    'S':
  487.                 sscanf(option,"%d",&start_no);
  488.                 option += strlen(option);
  489.                 break;
  490.             case    't':
  491.             case    'T':
  492.                 sscanf(option,"%d",&end_no);
  493.                 option += strlen(option);
  494.                 break;
  495.             default:
  496.                 usage();
  497.                 exit(1);
  498.         }
  499.     }
  500. }
  501.